package com.wtwd.campus.service.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.common.RespEntity;
import com.wtwd.campus.dao.DeviceInfoMapper;
import com.wtwd.campus.dao.OffLineBufferCmdMapper;
import com.wtwd.campus.dao.WhiteListMapper;
import com.wtwd.campus.entity.*;
import com.wtwd.campus.service.DeviceInfoService;
import com.wtwd.campus.service.RedisService;
import com.wtwd.campus.service.WhiteListService;
import com.wtwd.campus.utils.CommandNumberUtil;
import com.wtwd.campus.utils.CommandSendUtils;
import com.wtwd.campus.utils.GeneralSequenceUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author mjy
 * @date 2021/06/29
 * @description
 */
@Service
public class WhiteListServiceImpl implements WhiteListService {

    @Autowired
    private WhiteListMapper whiteListMapper;
    @Autowired
    private CommandSendUtils commandSendUtils;
    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DeviceInfoMapper deviceInfoMapper;
    @Autowired
    private OffLineBufferCmdMapper offLineBufferCmdMapper;

    @Override
    public List<DeviceWhiteList> getWhiteListByDeviceId(Integer deviceId, Integer type) {
        return whiteListMapper.getWhiteListByDeviceId(deviceId, type);
    }

    @Override
    public RespEntity deleteDeviceWhiteList(Integer id, SysUser sysUser) {
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(id);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICEINFO_ERROR);
        }
        String commandNumber = getCurTime();
        //1.判断设备是否在线
        boolean deviceOnline = commandSendUtils.deviceOnline(deviceInfo.getImei());
        //2.构建指令所需参数
        DeviceWhiteList deviceWhiteList = whiteListMapper.getDeviceWhiteInfoById(id);
        boolean isSend = commandSendUtils.delWhiteCall(deviceInfo.getImei(), commandNumber, deviceWhiteList.getSequence(), deviceOnline, sysUser.getUserId(), false);
        if (!isSend) {
            return new RespEntity(RespCode.FAILED);
        }
        //3.将数据库中该条白名单状态改为待删除
        deviceWhiteList.setStatus(Constants.CLASSES_PATTERN_STAY_DELETE);
        Integer rest = whiteListMapper.updateWhiteList(deviceWhiteList);
        return new RespEntity(rest > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RespEntity addDeviceWhiteList(Map<String, Object> deviceWhiteMap, SysUser sysUser) {
        Integer deviceId = (Integer) deviceWhiteMap.get("deviceId");
        String imei = (String) deviceWhiteMap.get("imei");
        Integer type = (Integer) deviceWhiteMap.get("type");
        String deviceWhiteCalls1 = (String) deviceWhiteMap.get("deviceWhiteCalls");
        List<DeviceWhiteCall> deviceWhiteCalls = new ArrayList<>();
        if (StringUtils.isNotBlank(deviceWhiteCalls1)) {
            deviceWhiteCalls = JSONArray.parseArray(deviceWhiteCalls1, DeviceWhiteCall.class);
        }
        //查看该设备是否在线
        boolean online = commandSendUtils.deviceOnline(imei);
        String commandNumber = CommandNumberUtil.getCurTime();
        ArrayList<DeviceWhiteCall> batchAddList = new ArrayList<>();//批量添加集合,添加状态为待添加
        ArrayList<Integer> batchUpdateList = new ArrayList<>();//批量修改白名单id,只修改状态，将状态值修改为待修改
        ArrayList<Integer> bathDelList = new ArrayList<>();//记录批量删除白名单状态为待删除
        //记录,批量发送指令的数据
        //定义标志（保证对比只会执行一次）
        Integer count=0;
        List<Map<String, Object>> deviceWhiteCallList = new ArrayList<>();
        if (deviceWhiteCalls != null && deviceWhiteCalls.size() > 0) {
            //处理之前该设备现在所有白名单,亲情号数据(所有状态的数据)
            List<DeviceWhiteList> deviceWhiteLists = whiteListMapper.getWhiteListByDeviceId(deviceId, null);
            //前端传过来待状态数据,更新数据最新状态，然后过滤掉待状态
            Iterator<DeviceWhiteCall> iterator1 = deviceWhiteCalls.iterator();
            while (iterator1.hasNext()){
                DeviceWhiteCall whiteCall = iterator1.next();
                if (deviceWhiteLists!=null&&deviceWhiteLists.size()>0){
                    for (DeviceWhiteList deviceWhiteList : deviceWhiteLists) {
                        if (whiteCall.getId()!=null&&whiteCall.getId().equals(deviceWhiteList.getId())){//如果主键id一致说明是同一组数据
                           //更新前端数据的最新状态
                            whiteCall.setStatus(deviceWhiteList.getStatus());
                            break;
                        }
                    }
                }
            }
            //过滤掉前端传入非正常状态数据,留下正常数据(可操作数据)
            deviceWhiteCalls = deviceWhiteCalls.stream().filter(e -> e.getStatus().equals(Constants.DEVICE_WHITE_NORMAl)).collect(Collectors.toList());
            System.out.println("白名单或者亲情号过滤掉后的正常数据:"+deviceWhiteCalls);
            //赛选删除(如果数据库中有，而传过来没有，则删除)
            //获取正常数据集合
            for (DeviceWhiteCall deviceWhiteCall : deviceWhiteCalls) {//此处为前端传过来的数据
                List<DeviceWhiteList> collect=new ArrayList<>();
                if (deviceWhiteCall.getIsAffection().equals(0)){//白名单数据
                   collect = deviceWhiteLists.stream().filter(e -> e.getStatus().equals(Constants.DEVICE_WHITE_NORMAl)&&e.getSequence()>Constants.DEVICE_LOVE_PHONE_END).collect(Collectors.toList());
                }else if (deviceWhiteCall.getIsAffection().equals(1)){//情亲号数据
                    collect = deviceWhiteLists.stream().filter(e -> e.getStatus().equals(Constants.DEVICE_WHITE_NORMAl)&&e.getSequence()>=Constants.DEVICE_LOVE_PHONE_START&&e.getSequence()<=Constants.DEVICE_LOVE_PHONE_END).collect(Collectors.toList());
                }
                //过滤掉只留下正常(数据库中过滤掉的白名单或者亲情号数据)
                if (collect != null && collect.size() > 0&&count==0) {
                    count=1;
                    for (DeviceWhiteList deviceWhiteList : collect) {
                        //定义删除标志
                        boolean delFlag = true;
                        for (DeviceWhiteCall deviceWhiteCallOld : deviceWhiteCalls) {
                            if (deviceWhiteCallOld.getId() != null) {
                                if (deviceWhiteList.getId().equals(deviceWhiteCallOld.getId())) {//如果数据库中有，传过来也有，则不删除
                                    delFlag = false;
                                    break;
                                }
                            }
                        }
                        if (delFlag) {
                            //记录删除
                            //2.将该数据记录为待删除数据
                            bathDelList.add(deviceWhiteList.getId());
                            //3.构建指令发送记录数据
                            HashMap<String, Object> map = new HashMap<>();
                            map.put("name", "");
                            map.put("phone", "");//将手机号记录为空
                            map.put("sequence", deviceWhiteList.getSequence());
                            deviceWhiteCallList.add(map);
                            continue;
                        }
                    }
                }
                //区分添加数据，与待添加数据
                if (deviceWhiteCall.getId() == null) {
                    //此处数据为待添加数据
                    //1.鉴别白名单号码，或者亲情号码是否重复添加
                    //2.鉴别是否已经达到白名单上限
                    //3.根据类型初始化生成序列号
                    int sequence = 0;
                    if (deviceWhiteCall.getIsAffection().equals(Constants.WHITE_CALL)) {//如果是白名单数据
                        List<DeviceWhiteList> lists = deviceWhiteLists.stream().filter(e -> e.getSequence() > Constants.DEVICE_LOVE_PHONE_END).collect(Collectors.toList());
                        if (lists != null && lists.size() >= 17) {//达到白名单上限
                            return new RespEntity(RespCode.DEVICE_WHITE_LIST);
                        }
                        //鉴别白名单是否重复添加
                        if (lists != null && lists.size() > 0) {
                            for (DeviceWhiteList deviceWhiteList : lists) {
                                if (deviceWhiteCall.getPhone().equals(deviceWhiteList.getWhitePhone())) {
                                    return new RespEntity(RespCode.EXIST_DEVICE_WHITE_LIST);
                                }
                            }
                        }
                        if (lists == null || lists.size() == 0) {//如果白名单列表为空,序列号初始值为4
                            sequence = 7;
                        } else {
                            List<Integer> sequenceList = lists.stream().map(deviceWhite -> deviceWhite.getSequence()).collect(Collectors.toList());
                            sequence = GeneralSequenceUtils.generalSequence2(sequenceList, deviceWhiteCall.getIsAffection());
                        }
                    } else {//亲情号数据
                        List<DeviceWhiteList> lists = deviceWhiteLists.stream().filter(e -> e.getSequence()>=Constants.DEVICE_LOVE_PHONE_START&&e.getSequence()<=Constants.DEVICE_LOVE_PHONE_END).collect(Collectors.toList());
                        if (lists != null && lists.size() >= 3) {//达到白名单上限
                            return new RespEntity(RespCode.DEVICE_AFFECTION_LIST);
                        }
                        if (lists != null && lists.size() > 0) {
                            for (DeviceWhiteList deviceWhiteList : lists) {
                                if (deviceWhiteCall.getPhone().equals(deviceWhiteList.getWhitePhone())) {
                                    return new RespEntity(RespCode.EXIST_DEVICE_WHITE_LIST);
                                }
                            }
                        }
                        if (lists == null || lists.size() == 0) {//如果白名单列表为空,序列号初始值为4
                            sequence = 4;
                        } else {
                            List<Integer> sequenceList = lists.stream().map(deviceWhite -> deviceWhite.getSequence()).collect(Collectors.toList());
                            sequence = GeneralSequenceUtils.generalSequence2(sequenceList, deviceWhiteCall.getIsAffection());
                        }
                    }
                    //1.记录添加操作数据库添加白名单的数据
                    deviceWhiteCall.setCommandNumber(commandNumber);
                    deviceWhiteCall.setSequence(sequence);
                    deviceWhiteCall.setStatus(Constants.DEVICE_WHITE_STAY_ADD);
                    batchAddList.add(deviceWhiteCall);
                    //2.记录发送指令所需数据
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("name", deviceWhiteCall.getName());
                    map.put("phone", deviceWhiteCall.getPhone());
                    map.put("sequence", sequence);
                    deviceWhiteCallList.add(map);
                    //3.将该数据记录到该设备的白名单列表中(模拟已经插入)
                    DeviceWhiteList deviceWhiteList = new DeviceWhiteList();
                    deviceWhiteList.setDeviceId(deviceId);
                    deviceWhiteList.setCommandNumber(commandNumber);
                    deviceWhiteList.setSequence(sequence);
                    deviceWhiteList.setStatus(Constants.DEVICE_WHITE_STAY_ADD);
                    deviceWhiteList.setIsAffection(deviceWhiteCall.getIsAffection());
                    deviceWhiteList.setWhiteName(deviceWhiteCall.getName());
                    deviceWhiteList.setWhitePhone(deviceWhiteCall.getPhone());
                    deviceWhiteLists.add(deviceWhiteList);
                } else {//此处数据为待修改数据
                    //分析数据，带id的数据里面有哪些增加，哪些是删除，哪些是修改
                    //1.找出增加数据（带过来虽然有id但在数据库中没有这个id,说明这个数据被其他端删除掉了,需要重新增,如果其他端只是修改了,他处在修改状态，不记录）
                    //定义新增标识符
                    boolean addFlag = true;
                    if (deviceWhiteLists != null && deviceWhiteLists.size() > 0) {
                        for (DeviceWhiteList deviceWhiteList : deviceWhiteLists) {
                            if (deviceWhiteList.getId() != null) {//此处判空是因为，里面含有模拟新增数据
                                if (deviceWhiteList.getId().equals(deviceWhiteCall.getId())) {//存在此id数据则不进行新增操作
                                    addFlag = false;
                                    break;
                                }
                            }
                        }
                    }
                    if (addFlag) {//如果数据库中不含有这个id,执行添加操作(重新添加,流水号)
                        deviceWhiteCall.setCommandNumber(commandNumber);
                        //重新生成序列号
                        //3.根据类型初始化生成序列号
                        int sequence = 0;
                        if (deviceWhiteCall.getIsAffection().equals(Constants.WHITE_CALL)) {//如果是白名单数据
                            List<DeviceWhiteList> lists = deviceWhiteLists.stream().filter(e -> e.getSequence() > Constants.DEVICE_LOVE_PHONE_END).collect(Collectors.toList());
                            if (lists != null && lists.size() >= 17) {//达到白名单上限
                                return new RespEntity(RespCode.DEVICE_WHITE_LIST);
                            }
                            if (lists == null || lists.size() == 0) {//如果亲情号列表为空,序列号初始值为4
                                sequence = 7;
                            } else {
                                List<Integer> sequenceList = lists.stream().map(deviceWhite -> deviceWhite.getSequence()).collect(Collectors.toList());
                                sequence = GeneralSequenceUtils.generalSequence2(sequenceList, deviceWhiteCall.getIsAffection());
                            }
                        } else {//亲情号数据
                            List<DeviceWhiteList> lists = deviceWhiteLists.stream().filter(e -> e.getSequence()>=Constants.DEVICE_LOVE_PHONE_START&&e.getSequence()<=Constants.DEVICE_LOVE_PHONE_END).collect(Collectors.toList());
                            if (lists != null && lists.size() >= 3) {//达到白名单上限
                                return new RespEntity(RespCode.DEVICE_AFFECTION_LIST);
                            }
                            if (lists == null || lists.size() == 0) {//如果亲情号列表为空,序列号初始值为4
                                sequence = 4;
                            } else {
                                List<Integer> sequenceList = lists.stream().map(deviceWhite -> deviceWhite.getSequence()).collect(Collectors.toList());
                                sequence = GeneralSequenceUtils.generalSequence2(sequenceList, deviceWhiteCall.getIsAffection());
                            }
                        }
                        deviceWhiteCall.setSequence(sequence);
                        deviceWhiteCall.setStatus(Constants.DEVICE_WHITE_STAY_ADD);
                        batchAddList.add(deviceWhiteCall);
                        //2.记录发送指令所需数据
                        HashMap<String, Object> map = new HashMap<>();
                        map.put("name", deviceWhiteCall.getName());
                        map.put("phone", deviceWhiteCall.getPhone());
                        map.put("sequence", sequence);
                        deviceWhiteCallList.add(map);
                        //3.将该数据记录到该设备的白名单列表中(模拟已经插入)
                        DeviceWhiteList deviceWhiteList = new DeviceWhiteList();
                        deviceWhiteList.setDeviceId(deviceId);
                        deviceWhiteList.setCommandNumber(commandNumber);
                        deviceWhiteList.setSequence(sequence);
                        deviceWhiteList.setStatus(Constants.DEVICE_WHITE_STAY_ADD);
                        deviceWhiteList.setIsAffection(deviceWhiteCall.getIsAffection());
                        deviceWhiteList.setWhiteName(deviceWhiteCall.getName());
                        deviceWhiteList.setWhitePhone(deviceWhiteCall.getPhone());
                        deviceWhiteLists.add(deviceWhiteList);
                        continue;
                    }
                    //1.鉴别前端发送过来的数据是否需要去修改(在id一样的情况下,鉴别白名单名称和号码是否一致)
                    //2.鉴别修改后的手机号(除开本身)是否与现在数据库中手机号重复
                    Iterator<DeviceWhiteList> iterator = deviceWhiteLists.iterator();
                    while (iterator.hasNext()) {
                        DeviceWhiteList deviceWhiteList = iterator.next();
                        if (deviceWhiteList.getId() != null && deviceWhiteList.getId().equals(deviceWhiteCall.getId())) {
                            //鉴别该白名单是否发生过修改
                            if (!(deviceWhiteCall.getPhone().equals(deviceWhiteList.getWhitePhone()) && deviceWhiteCall.getName().equals(deviceWhiteList.getWhiteName()))) {
                                //记录修改数据id(修改只更新其状态为待修改)
                                batchUpdateList.add(deviceWhiteCall.getId());
                                //2.记录发送指令所需数据
                                HashMap<String, Object> map = new HashMap<>();
                                map.put("name", deviceWhiteCall.getName());
                                map.put("phone", deviceWhiteCall.getPhone());
                                map.put("sequence", deviceWhiteCall.getSequence());
                                deviceWhiteCallList.add(map);
                                //模拟修改记录
                                DeviceWhiteList deviceWhite = new DeviceWhiteList();
                                deviceWhite.setDeviceId(deviceId);
                                deviceWhite.setCommandNumber(commandNumber);
                                deviceWhite.setSequence(deviceWhiteCall.getSequence());
                                deviceWhite.setStatus(Constants.DEVICE_WHITE_STAY_ADD);
                                deviceWhite.setIsAffection(deviceWhiteCall.getIsAffection());
                                deviceWhite.setWhiteName(deviceWhiteCall.getName());
                                deviceWhite.setWhitePhone(deviceWhiteCall.getPhone());
                                deviceWhiteList = deviceWhite;
                                break;
                            }
                        } /*else {//此处鉴别手机号是否与其他项重复
                            if (deviceWhiteList.getWhitePhone().equals(deviceWhiteCall.getPhone())) {
                                return new RespEntity(RespCode.EXIST_DEVICE_AFFECTION_LIST);
                            }
                        }*/
                    }
                }
            }
        } else {
            List<DeviceWhiteList> deviceWhiteLists = whiteListMapper.getWhiteListByDeviceIdAndStarts(deviceId, Constants.DEVICE_WHITE_NORMAl);
            List<DeviceWhiteList> collect=new ArrayList<>();
            if (type.equals(0)){
                //过滤掉亲情亲号数据(留下白名单)
               collect = deviceWhiteLists.stream().filter(e -> e.getSequence() > Constants.DEVICE_LOVE_PHONE_END).collect(Collectors.toList());
            }else if (type.equals(1)){
                //过滤掉白名单数据
               collect = deviceWhiteLists.stream().filter(e -> e.getSequence()>=Constants.DEVICE_LOVE_PHONE_START&&e.getSequence()<=Constants.DEVICE_LOVE_PHONE_END).collect(Collectors.toList());
            }
            //如果传过来的集合数据为空的话，说明他是要删除该设备所有正常的数据
            //1.查询所有是正常数据的该白名单的
            if (collect != null && collect.size() > 0) {
                for (DeviceWhiteList deviceWhiteList : collect) {
                    //2.将该数据记录为待删除数据
                    bathDelList.add(deviceWhiteList.getId());
                    //3.构建指令发送记录数据
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("name", "");
                    map.put("phone", "");
                    map.put("sequence", deviceWhiteList.getSequence());//将流水号记录为空
                    deviceWhiteCallList.add(map);
                }
            }
        }
        if (!online) {
            //处理离线缓存参数
            OffLineBufferCmd offLineBuffer = offLineBufferCmdMapper.selectOffLineBufferCmd(imei, Constants.ALL_WHITELIST_NUMBER, null);
            if (offLineBuffer != null) {
                String param = offLineBuffer.getParam();
                if (StringUtils.isNotBlank(param)) {
                    MqSetAllWhiteCall mqSetAllWhiteCall = (MqSetAllWhiteCall) JSONObject.parseObject(param, MqSetAllWhiteCall.class);
                    List<Map<String, Object>> whiteCallList = mqSetAllWhiteCall.getWhiteCallList();
                    if (whiteCallList != null && whiteCallList.size() > 0) {
                        Iterator<Map<String, Object>> iterator = whiteCallList.iterator();
                        while (iterator.hasNext()) {
                            Map<String, Object> next = iterator.next();
                            if (deviceWhiteCallList != null && deviceWhiteCallList.size() > 0) {
                                for (Map<String, Object> map : deviceWhiteCallList) {
                                    if (map.containsKey("sequence")&&map.get("sequence").equals(next.get("sequence"))) {//只对比卡槽,卡槽相同，替换
                                        iterator.remove();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    deviceWhiteCallList.addAll(whiteCallList);
                }
            }
        }
        boolean sendBoolean=true;
        //数据收集完毕执行命令的下发与数据库信息的同步
        if (deviceWhiteCallList!=null&&deviceWhiteCallList.size()>0){
        sendBoolean = commandSendUtils.setAllWhiteCall(deviceWhiteCallList, imei, commandNumber, online, sysUser.getUserId(), false);
        }
        if (sendBoolean) {
            //执行添加删除，和修改
            if (batchAddList != null && batchAddList.size() > 0) {
                whiteListMapper.bathAddWhiteCall(batchAddList);
            }
            if (batchUpdateList != null && batchUpdateList.size() > 0) {
                whiteListMapper.updateWhiteListStarts(batchUpdateList, Constants.DEVICE_WHITE_STAY_UPDATE);
            }
            if (bathDelList != null && bathDelList.size() > 0) {
                whiteListMapper.updateWhiteListStarts(bathDelList, Constants.DEVICE_WHITE_DELETE);
            }
        }
        return new RespEntity(RespCode.SUCCESS);
    }

    @Override
    public int addDeviceWhiteCall(DeviceWhiteCall whiteCall) {
        return whiteListMapper.addDeviceWhiteCall(whiteCall);
    }

    @Override
    public int updateWhiteCallStatus(Integer deviceId, Integer sequence, Integer status, String commandNumber) {
        return whiteListMapper.updateDeviceWhiteCallStatus(deviceId, sequence, status, commandNumber);
    }

    @Override
    public Integer deletePhoneByDeviceId(Integer deviceId) {
        return whiteListMapper.deletePhoneByDeviceId(deviceId);
    }

    @Override
    public Integer bathAddWhiteCall(List<DeviceWhiteCall> bathAddFamilyData) {
        return whiteListMapper.bathAddWhiteCall(bathAddFamilyData);
    }


    /**
     * 获取当前时间的时分秒（HHmmss）
     *
     * @return
     */
    public String getCurTime() {
        Date d = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("HH:mm:ss");
        String format = sbf.format(d);
        String[] split = format.split(":");
        String time = split[0].concat(split[1]).concat(split[2]);
        return time;
    }
}
